#include <iostream>
#include <unistd.h>
#include <sys/types.h>
#include "Protocol.hpp"
#include "Socket.hpp"
#include "InetAddr.hpp"
#include "Log.hpp"
using namespace socket_ns;
using namespace protocol_ns;

void Usage(std::string pro)
{
    // std::cout << "Usage:\n\t" << pro << " server_ip server_port\n";
    std::cout << "Usage:\n\t" << pro << "server_ip server_port\n";
}

// 客户端需要实现收消息和发消息是同步的 需要使用多线程 可以发消息的同时也能够收消息
int main(int argn, char *argv[])
{
    if (argn < 3)
    {
        Usage(argv[0]);
        exit(1);
    }

    std::string server_ip = argv[1];
    uint16_t server_port = std::stoi(argv[2]);
    InetAddr serveraddr(server_ip, server_port);

    std::unique_ptr<Socket> client = std::make_unique<TcpSocket>();
    bool res = client->BuildClientSocket(serveraddr);

    // 建立连接成功，开始通信
    Factory factory;
    std::string inbuffer;
    while (res)
    {
        // std::string str;
        // for (int i = 0; i < 5; i++)
        // {
        //     std::cout << "----begin----\n";
        //     // 1.生成请求
        //     auto req = factory.BulidRequest();
        //     // 2.序列化req
        //     std::string send_str;
        //     req->Serialize(&send_str);
        //     std::cout << "Serialize:\n"
        //               << send_str;
        //     // 3.对json串加上报头
        //     send_str = Encode(send_str);
        //     std::cout << "Encode:\n"
        //               << send_str;

        //     str += send_str;
        //     sleep(1); // 每隔1s发一次请求
        // }

        std::cout << "----begin----\n";
        // 1.生成请求
        auto req = factory.BulidRequest();
        // 2.序列化req
        std::string send_str;
        req->Serialize(&send_str);
        std::cout << "Serialize:\n"
                  << send_str;
       
        // 3.对json串加上报头
        send_str = Encode(send_str);
        std::cout << "Encode:\n"
                  << send_str;
       
        // 4.发送到网络中
        client->Send(send_str);
        // 5.接受来自服务器的数据
        int n = client->Recv(&inbuffer);
        // 5.1服务器退出，则客户端退出
        if (n <= 0)
            break;
        // 6.分析数据，得到有效载荷
        std::string package = Decode(inbuffer);
        // 6.1读取不是一个完整的报文，继续读
        if (package.empty())
            continue;
        // 7.package一定是一个json串，将其反序列化
        auto resp = factory.BulidResponse();
        resp->Deserialize(package);
        // 8.输出结果
        std::cout << "[server echo#]" << resp->_res << "[" << resp->_code << "]" << std::endl;
        std::cout << "----end----\n";
    }

    return 0;
}